/*
 * storage.c
 *
 *  Created on: Dec 25, 2013
 *      Author: Ahmed
 */

/*
 * This file contains all the functions that store and restore information to the EEPROM
 */

/* Includes */
#include "stm32f10x.h"
#include "main.h"
#include "spieeprom.h"
#include "datetime.h"

extern uint32_t	RTC_Alarm_Count;			// Holds number of secs left to the next reading

/*
 * Stores the start of logging timestamp and logging frequency at a specific EEPROM address.
 * We convert everything here to bytes to match the eeprom storage
 * format which is byte.
 * Recording a samples start with:
 *		- LOG_HEADER_ID as a separator
 *		- start logging timestamp.
 *		- start logging timestamp.
 *		- number of seconds to next sample acquisition
 *
 *		Total bytes to write is 1+4+4+4=13 bytes.
 *
*/

void storeLogHeader(uint16_t eepromWriteAddr, LogHeaderDef *logHeader) {
	uint8_t logHeaderArray[13];
	logHeaderArray[0] = LOG_HEADER_ID;
	logHeaderArray[1] = (logHeader->startLogTime >> 24) & 0xFF;
	logHeaderArray[2] = (logHeader->startLogTime >> 16) & 0xFF;
	logHeaderArray[3] = (logHeader->startLogTime >>  8) & 0xFF;
	logHeaderArray[4] = (logHeader->startLogTime      ) & 0xFF;

	logHeaderArray[5] = (logHeader->stopLogTime >> 24) & 0xFF;
	logHeaderArray[6] = (logHeader->stopLogTime >> 16) & 0xFF;
	logHeaderArray[7] = (logHeader->stopLogTime >>  8) & 0xFF;
	logHeaderArray[8] = (logHeader->stopLogTime      ) & 0xFF;

	logHeaderArray[9] =  (RTC_Alarm_Count >> 24) & 0xFF;
	logHeaderArray[10] = (RTC_Alarm_Count >> 16) & 0xFF;
	logHeaderArray[11] = (RTC_Alarm_Count >>  8) & 0xFF;
	logHeaderArray[12] = (RTC_Alarm_Count      ) & 0xFF;

	spiEE_WriteAcrossPages(logHeaderArray, eepromWriteAddr, sizeof_logHeaderStruct());
}

/*
 * Reads a log header from the EEPROM back into a logHeader structure
 *
*/
void readLogHeader(uint16_t eepromReadAddr, LogHeaderDef *logHeader) {
	uint8_t eeprom_logHeader[13],i;

	// Initialize with zeros otherwise the following ORing will give wrong results
	logHeader->startLogTime=0;
	logHeader->stopLogTime=0;
	logHeader->RTC_Alarm_Count=0;

	spiEE_Read(eeprom_logHeader,eepromReadAddr,sizeof(eeprom_logHeader));

	logHeader->separator = eeprom_logHeader[0];

	for (i = 0; i < 3; i++) {
		logHeader->startLogTime |= eeprom_logHeader[i+1];
		logHeader->startLogTime <<=8;
	}
	logHeader->startLogTime |= eeprom_logHeader[4];

	for (i = 0; i < 3; i++) {
		logHeader->stopLogTime |= eeprom_logHeader[i+5];
		logHeader->stopLogTime <<=8;
	}
	logHeader->stopLogTime |= eeprom_logHeader[8];

	for (i = 0; i < 3; i++) {
		logHeader->RTC_Alarm_Count |= eeprom_logHeader[i+9];
		logHeader->RTC_Alarm_Count <<=8;
	}
	logHeader->RTC_Alarm_Count |= eeprom_logHeader[12];
}

/*
 * Stores the temperature and Humidity as two byte.
 * Recording a samples start with:
 *
*/
void storeLogData(uint16_t eepromWriteAddr, dataRecDef *dataRecord) {
	uint8_t logData[2];
	logData[0]= dataRecord->temperature;
	logData[1]= dataRecord->humidity;
	spiEE_WriteAcrossPages(logData, eepromWriteAddr, sizeof(logData));
}

void readLogData(uint16_t eepromReadAddr, dataRecDef *dataRecord) {
	uint8_t logData[2];
	spiEE_Read(logData,eepromReadAddr,sizeof(logData));
	dataRecord->temperature = logData[0];
	dataRecord->humidity = logData[1];
}

/*
 * Takes the userSettings structure and stores its content in the EEPROM
 * This function serializes the userSettings content. So if the userSettings change, this function
 * must change as well
 *	  uint8_t	ID;					// use it to tell if the userSetting was stored on EEPROM or not
 *	  uint32_t	startLogTime;		// Time stamp for when logging should start or current date and time if we should have started
 *	  uint32_t	stopLogTime;		// Time stamp for when logging should stop or stopped.
 *	  uint8_t 	freq_type;			// minutes (0), hours (1), days (2)
 *	  uint8_t 	freq_val;			// value being 1-60, 1-24, 1-30
 *	  uint8_t 	log_update_mode;	// Log from start or append to last log
 *	  uint16_t	eepromWriteAddr;	// Hold the last written address when logging has stopped.
 *	  	  	  	  	  	  	  	  	// Needed to resume logging in log append mode
 *	  uint8_t 	LCD_timeout;		// LCD to turn off after 15/30 secs
 *	  uint8_t 	LCD_light_timeout;	// LCD Light turns off after 5/10/15 secs
 */
void storeUserSettings (uint16_t eepromWriteAddr, userSettingsDef *userSettings){
	uint8_t userSettingsArray[16];

	userSettingsArray[0]=userSettings->ID;

	userSettingsArray[1] = (userSettings->startLogTime >> 24) & 0xFF;
	userSettingsArray[2] = (userSettings->startLogTime >> 16) & 0xFF;
	userSettingsArray[3] = (userSettings->startLogTime >>  8) & 0xFF;
	userSettingsArray[4] = (userSettings->startLogTime      ) & 0xFF;

	userSettingsArray[5] = (userSettings->stopLogTime >> 24) & 0xFF;
	userSettingsArray[6] = (userSettings->stopLogTime >> 16) & 0xFF;
	userSettingsArray[7] = (userSettings->stopLogTime >>  8) & 0xFF;
	userSettingsArray[8] = (userSettings->stopLogTime      ) & 0xFF;

	userSettingsArray[9] = userSettings->freq_type;
	userSettingsArray[10] = userSettings->freq_val;

	userSettingsArray[11] = userSettings->log_update_mode;

	userSettingsArray[12] = (userSettings->eepromWriteAddr >>  8) & 0xFF;
	userSettingsArray[13] = (userSettings->eepromWriteAddr      ) & 0xFF;

	userSettingsArray[14] = userSettings->LCD_timeout;
	userSettingsArray[15] = userSettings->LCD_light_timeout;

	spiEE_WriteAcrossPages(userSettingsArray, eepromWriteAddr, sizeof_userSettingsStruct());
}

/*
 * Reads back the stored userSettings from the EEPROM at address 0 to the userSettingsStruct
 * This function serializes the userSettings content. So if the userSettings change, this function
 * must change as well
 *	  uint8_t	ID;					// use it to tell if the userSetting was stored on EEPROM or not
 *	  uint32_t	startLogTime;		// Time stamp for when logging should start or current date and time if we should have started
 *	  uint32_t	stopLogTime;		// Time stamp for when logging should stop or stopped.
 *	  uint8_t 	freq_type;			// minutes (0), hours (1), days (2)
 *	  uint8_t 	freq_val;			// value being 1-60, 1-24, 1-30
 *	  uint8_t 	log_update_mode;	// Log from start or append to last log
 *	  uint16_t	eepromWriteAddr;	// Hold the last written address when logging has stopped.
 *	  	  	  	  	  	  	  	  	// Needed to resume logging in log append mode
 *	  uint8_t 	LCD_timeout;		// LCD to turn off after 15/30 secs
 *	  uint8_t 	LCD_light_timeout;	// LCD Light turns off after 5/10/15 secs
 */
void readUserSettings (uint16_t eepromReadAddr,userSettingsDef *userSettings){
	uint8_t userSettingsArray[16],i;

	spiEE_Read(userSettingsArray,eepromReadAddr,sizeof_userSettingsStruct());

	userSettings->ID = userSettingsArray[0];

	for (i = 0; i < 3; i++) {
		userSettings->startLogTime |= userSettingsArray[i+1];
		userSettings->startLogTime <<=8;
	}
	userSettings->startLogTime |= userSettingsArray[4];

	for (i = 0; i < 3; i++) {
		userSettings->stopLogTime |= userSettingsArray[i+5];
		userSettings->stopLogTime <<=8;
	}
	userSettings->stopLogTime |= userSettingsArray[8];

	userSettings->freq_type = userSettingsArray[9];
	userSettings->freq_val = userSettingsArray[10];
	userSettings->log_update_mode = userSettingsArray[11];

	userSettings->eepromWriteAddr |= userSettingsArray[12];
	userSettings->eepromWriteAddr <<=8;
	userSettings->eepromWriteAddr |= userSettingsArray[13];

	userSettings->LCD_timeout = userSettingsArray[14];
	userSettings->LCD_light_timeout = userSettingsArray[15];
}
